package cn.colat.micse.common.pojo.vo;

import cn.colat.micse.common.code.ResCode;
import cn.colat.micse.common.constant.CommonConstant;
import cn.colat.micse.common.constant.DateTimeConstant;
import cn.colat.micse.common.utils.IDUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.MDC;

import java.util.Date;

@Data
@ApiModel(value = "通用响应体")
@AllArgsConstructor
@NoArgsConstructor
public class ResBody<T> {
    /**
     * 响应码
     */
    @ApiModelProperty(value = "响应码", required = true, example = "200")
    public Integer code;
    /**
     * 响应字符码
     */
    @ApiModelProperty(value = "响应字符码", required = true, example = "Query_Success")
    public String codeText;
    /**
     * 是否成功
     */
    @ApiModelProperty(value = "是否成功", required = true, example = "true")
    public Boolean success;
    /**
     * 响应消息
     */
    @ApiModelProperty(value = "响应消息", required = true, example = "请求成功")
    public String message;
    /**
     * 请求id
     */
    @ApiModelProperty(value = "请求id", required = true, example = "lDiRZ4sF6NTJKtV7SiXsw")
    public String requestId;
    /**
     * 响应时间
     */
    @JsonFormat(pattern = DateTimeConstant.YYYY_MM_DD_HH_mm_ss, timezone = DateTimeConstant.TIME_ZONE_DEFAULT)
    @ApiModelProperty(value = "响应时间", required = true, example = "2023-01-01 00:00:00")
    public Date dateTime;
    /**
     * 响应数据
     */
    @ApiModelProperty(value = "响应数据", example = "qMwk4ERnNJap8PPGytjQ2FHT9ix9XWik")
    public T data;

    /**
     * 成功响应
     *
     * @param data 响应数据
     * @return 响应体
     */
    public static <T> ResBody<T> success(T data) {
        ResBody<T> body = new ResBody<>();
        body.setCode(ResCode.REQUEST_SUCCESS.getCode());
        body.setCodeText(ResCode.REQUEST_SUCCESS.getCodeText());
        body.setSuccess(true);
        body.setData(data);
        body.setMessage(ResCode.REQUEST_SUCCESS.getMessage());
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }


    /**
     * 成功响应
     *
     * @return 响应体
     */
    public static <T> ResBody<T> successMessage(String message) {
        ResBody<T> body = new ResBody<>();
        body.setCode(ResCode.REQUEST_SUCCESS.getCode());
        body.setCodeText(ResCode.REQUEST_SUCCESS.getCodeText());
        body.setSuccess(true);
        body.setData(null);
        body.setMessage(message);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    /**
     * 失败响应
     *
     * @param message 错误消息
     * @return 响应体
     */
    public static <T> ResBody<T> failMessage(String message) {
        ResBody<T> body = new ResBody<>();
        body.setCode(ResCode.REQUEST_ERROR.getCode());
        body.setCodeText(ResCode.REQUEST_ERROR.getCodeText());
        body.setSuccess(false);
        body.setMessage(message);
        body.setData(null);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    /**
     * 失败响应
     *
     * @param message 错误消息
     * @return 响应体
     */
    public static <T> ResBody<T> failMessage(Integer code, String codeText, String message) {
        ResBody<T> body = new ResBody<>();
        body.setCode(code);
        body.setCodeText(codeText);
        body.setSuccess(false);
        body.setMessage(message);
        body.setData(null);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    /**
     * 失败响应
     *
     * @param resCode 错误消息
     * @return 响应体
     */
    public static <T> ResBody<T> failErrorCode(ResCode resCode) {
        ResBody<T> body = new ResBody<>();
        body.setCode(resCode.getCode());
        body.setCodeText(resCode.getCodeText());
        body.setSuccess(false);
        body.setMessage(resCode.getMessage());
        body.setData(null);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    /**
     * 失败响应
     *
     * @param resCode 错误消息
     * @param arg     可变响应消息
     * @return 响应体
     */
    public static <T> ResBody<T> failErrorCode(ResCode resCode, Object... arg) {
        resCode.format(arg);
        ResBody<T> body = new ResBody<>();
        body.setCode(resCode.getCode());
        body.setCodeText(resCode.getCodeText());
        body.setSuccess(false);
        body.setMessage(resCode.getMessage());
        body.setData(null);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    /**
     * 失败响应
     *
     * @param code    响应码
     * @param message 错误消息
     * @return 响应体
     */
    public static <T> ResBody<T> failMessage(Integer code, String message) {
        ResBody<T> body = new ResBody<>();
        body.setCode(code);
        body.setCodeText(ResCode.REQUEST_ERROR.getCodeText());
        body.setSuccess(false);
        body.setMessage(message);
        body.setData(null);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }


    /**
     * 失败响应，并且可以携带数据
     *
     * @param data 数据
     */
    public static <T> ResBody<T> failData(T data) {
        ResBody<T> body = new ResBody<>();
        body.setCode(ResCode.REQUEST_ERROR.getCode());
        body.setCodeText(ResCode.REQUEST_ERROR.getCodeText());
        body.setSuccess(false);
        body.setMessage(ResCode.REQUEST_ERROR.getMessage());
        body.setData(data);
        body.setRequestId(getRequestId());
        body.setDateTime(new Date());
        return body;
    }

    public static String getRequestId() {
        String reqId = MDC.get(CommonConstant.TRACE_ID);
        if (null == reqId) {
            reqId = IDUtils.nanoId();
        }
        return reqId;
    }
}
